// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: daniel

#include "coin2/exchange/base/api_base/fix/fix_coin_logger.h"

#include <glog/logging.h>

#include "coin2/exchange/base/api_base/fix/fix_message_utils.h"

namespace coin2::exchange::base::api_base::fix {

CoinLogFactory::CoinLogFactory(const FIX::SessionSettings& settings)
    : use_settings_(true), settings_(settings) {}

CoinLogFactory::CoinLogFactory(bool incoming, bool outgoing, bool event)
    : incoming_(incoming), outgoing_(outgoing), event_(event), use_settings_(false) {}

FIX::Log* CoinLogFactory::create() {
  bool incoming = false;
  bool outgoing = false;
  bool event = false;
  init(settings_.get(), incoming, outgoing, event);
  return new FixCoinLogger(incoming, outgoing, event);
}

FIX::Log* CoinLogFactory::create(const FIX::SessionID& session_id) {
  FIX::Dictionary settings;
  if (settings_.has(session_id)) {
    settings = settings_.get(session_id);
  }
  bool incoming = false;
  bool outgoing = false;
  bool event = false;
  init(settings, incoming, outgoing, event);
  return new FixCoinLogger(session_id, incoming, outgoing, event);
}

void CoinLogFactory::init(
    const FIX::Dictionary& settings,
    bool& incoming,
    bool& outgoing,
    bool& event) {
  if (use_settings_) {
    incoming = true;
    outgoing = true;
    event = true;

    if (settings.has(FIX::SCREEN_LOG_SHOW_INCOMING)) {
      incoming = settings.getBool(FIX::SCREEN_LOG_SHOW_INCOMING);
    }
    if (settings.has(FIX::SCREEN_LOG_SHOW_OUTGOING)) {
      outgoing = settings.getBool(FIX::SCREEN_LOG_SHOW_OUTGOING);
    }
    if (settings.has(FIX::SCREEN_LOG_SHOW_EVENTS)) {
      event = settings.getBool(FIX::SCREEN_LOG_SHOW_EVENTS);
    }
  } else {
    incoming = incoming_;
    outgoing = outgoing_;
    event = event_;
  }
}

void CoinLogFactory::destroy(FIX::Log* pLog) {
  if (pLog == nullptr) {
    std::cout << "pLog is null\n";
    return;
  }
  delete pLog;
}

FixCoinLogger::FixCoinLogger(bool incoming, bool outgoing, bool event)
    : prefix_("GLOBAL"), incoming_(incoming), outgoing_(outgoing), event_(event) {}

FixCoinLogger::FixCoinLogger(
    const FIX::SessionID& sessionID,
    bool incoming,
    bool outgoing,
    bool event)
    : prefix_(sessionID.toString()), incoming_(incoming), outgoing_(outgoing), event_(event) {}

void FixCoinLogger::clear() {
  // do nothing
}

void FixCoinLogger::backup() {
  // do nothing
}

void FixCoinLogger::onIncoming(const std::string& value) {
  if (!incoming_) {
    return;
  }
  LOG(INFO) << "\n<" << prefix_ << ", "
            << "incoming>" << std::endl
            << FixMessageUtils::ToJson(value) << std::endl;
}

void FixCoinLogger::onOutgoing(const std::string& value) {
  if (!outgoing_) {
    return;
  }
  LOG(INFO) << "\n<" << prefix_ << ", "
            << "outgoing>" << std::endl
            << FixMessageUtils::ToJson(value) << std::endl;
}

void FixCoinLogger::onEvent(const std::string& value) {
  if (!event_) {
    return;
  }
  LOG(INFO) << "\n<" << prefix_ << ", "
            << "event>" << std::endl
            << "  (" << value << ")" << std::endl;
}

}  // namespace coin2::exchange::base::api_base::fix
